0006. 面向对象的思维方式
- 1. 🎯 本节内容
- 2. 🫧 评价
- 3. 🤔 什么是“面向对象”(OOP, Object-Oriented Programming)的思维?
- 4. 🤔 OOP 的核心思想是?
- 5. 🤔 OOP 的四大基本特性是?
- 6. 🆚 面向对象 vs. 面向过程
- 7. 🤔 为什么 OOP 更适合复杂项目?
- 8. 🤔 为什么有人说 TS 是面向对象的 JS?
1. 🎯 本节内容
- OOP 思维
- OOP 的四大基本特性
- OOP 思维 vs. Procedural 思维
2. 🫧 评价
- 在接下来学习 TS 的过程中,我们会接触到很多和“面向对象开发”密切相关的知识点,这些点是 JS 中所没有的,同样也是我们需要掌握的重点。
- 身边从事前端工作的不少朋友,几乎都是习惯于使用“面向过程”的开发思维来撸代码的。如果你也是从 JS 过来的,你的开发思维很可能也更倾向于“面向过程”,那么学习 TS 之后,你需要尝试着学会从最初的面向过程开发,转为面相对象开发。当然,思维的转变显然是一个不那么容易的过程,慢慢来便是。
- 也不是说学会了“面向对象开发”这种思维方式之后,“面向过程开发”的思维方式就直接 out 了,全都用“面向对象”的方式来写代码。但是,至少需要学会这样的开发思维,至于用不用,那是另一回事儿。
- 面向对象的相关知识点,也是面试的常考题。
3. 🤔 什么是“面向对象”(OOP, Object-Oriented Programming)的思维?
- 面向对象不是“必须用类写代码”,而是一种以对象为中心、强调封装与协作的思维方式。
- 掌握它,能让你从“写功能”升级到“设计系统”。
- 和面向过程的思维方式对比,本质是思考的切入点不同:
- 面向过程:“怎么做” -> 函数和步骤
- 面向对象:“谁来做” -> 对象及其职责
4. 🤔 OOP 的核心思想是?
- 面向对象编程(OOP, Object-Oriented Programming)是一种编程范式,它将现实世界中的事物抽象为程序中的“对象”,并通过对象之间的交互来构建程序。
- 在 OOP 中,一切皆对象。
- 每个对象都有自己的状态(数据/属性)和行为(方法/函数)。
- 程序不再是“一系列步骤”,而是“一组协同工作的对象”。
- 举个例子:一辆“汽车”可以是一个对象:
- 属性(状态):品牌、颜色、速度
- 方法(行为):启动、加速、刹车
5. 🤔 OOP 的四大基本特性是?
| 特性 | 说明 |
|---|---|
| 封装(Encapsulation) | 将数据(属性)和操作数据的方法(行为)捆绑在一起,并对外隐藏内部实现细节。通过访问控制(如 private)保护对象状态,只暴露必要的接口。 |
| 继承(Inheritance) | 子类可以继承父类的属性和方法,实现代码复用。例如,“电动车”继承自“汽车”,自动拥有品牌、启动等能力,还能新增“充电”方法。 |
| 多态(Polymorphism) | 同一个接口可以有多种实现方式。例如,Animal 类有 speak() 方法,Dog 实现为“汪汪”,Cat 实现为“喵喵”,调用时根据实际对象类型执行不同逻辑。 |
| 抽象(Abstraction) | 提取出共性,忽略无关细节。比如我们只关心“能画的图形”有 draw() 方法,而不关心圆或方具体怎么画。TS 中可通过 abstract class 或 interface 实现。 |
6. 🆚 面向对象 vs. 面向过程
| 对比维度 | 面向过程(Procedural) | 面向对象(OOP) |
|---|---|---|
| 核心关注点 | “怎么做”——函数和步骤 | “谁来做”——对象及其职责 |
| 代码组织方式 | 函数 + 数据分离 | 数据和行为封装在对象中 |
| 扩展性 | 修改逻辑可能影响多个函数,耦合度高 | 通过继承、多态灵活扩展,低耦合 |
| 适用场景 | 简单脚本、一次性任务 | 中大型项目、需要长期维护和团队协作的系统 |
举个生活例子:
- 面向过程:做一道菜 = 洗菜 → 切菜 → 炒菜 → 装盘(一步步执行)
- 面向对象:厨房里有“厨师”对象、“锅”对象、“食材”对象,它们协作完成任务
- 优先考虑对象,再考虑具体的流程应该由谁来做
7. 🤔 为什么 OOP 更适合复杂项目?
- 模块化:每个类职责单一,便于理解和维护。
- 可复用:通过继承和组合,避免重复造轮子。
- 可测试:对象边界清晰,单元测试更容易。
- 团队协作:接口定义明确,多人开发互不干扰。
正因为这些优势,TypeScript 在 JS 基础上强化了 OOP 能力,让前端也能写出结构清晰、健壮可靠的大型应用。
8. 🤔 为什么有人说 TS 是面向对象的 JS?
先给结论:虽然 JavaScript 也能模拟面向对象(通过原型、ES6 class 等),但 TypeScript 通过静态类型、访问控制、接口、泛型等特性,为面向对象开发提供了更安全、清晰、可维护的编程模型,尤其适合中大型项目。因此,TS 被广泛认为是实现 OOP 的更优选择。
- 就面相对象开发而言,TS 新增了很多特性,其中有很多特性正是面相对象开发所需要的。
- 这些特性也是我们接下来学习的重点内容。
- TS 的类型系统弥补了 JS 在类型检查方面的诸多不足,它出现增强了 JS 面向对象的开发。
- 当然,在 JS 中也有类和对象,JS 本身也是支持面向对象的开发方式的,但是由于 JS 自身的问题,导致了很多面向对象的场景实现起来会出现诸多问题。
- 也就是说,直接使用 JS 实现面向对象,还不是很完善,很少开发者会优先用 JS 去写面向对象的代码。
- 但是,TS 出现后,我们就可以利用它编写出更加完善的面向对象的代码。
- 细节方面,比如为什么说 TS 比 JS 更合适,TS 具体都完善了哪些点,会在后续内容中详细介绍,这里仅作简单的说明。
- TypeScript(TS)比 JavaScript(JS)更适合实现“面向对象开发”(Object-Oriented Programming, OOP),主要体现在以下几个方面:
| 特性 | TypeScript | JavaScript |
|---|---|---|
| 类型系统 | 静态类型(编译时检查) | 动态类型(运行时确定) |
| 访问控制 | private / protected | 无(靠命名约定如 _) |
| 接口 | 支持 interface | 不支持 |
| 抽象类 | 支持 abstract class | 不支持 |
| 泛型 | 支持 | 不支持 |
| IDE 支持 | 极强(类型推导、重构等) | 有限 |
| 类型错误发现时机 | 编写/编译阶段(更早) | 运行时(更晚) |
8.1. 静态类型系统(Static Typing)
- TS 是 JavaScript 的超集,引入了静态类型检查,在编译阶段就能发现类型错误。
- 在面向对象开发中,类、接口、继承、多态等概念高度依赖类型约束。TS 的类型系统让这些概念更清晰、安全。
- JS 是动态类型语言,运行时才确定类型,容易在对象方法调用或属性访问时出错,且难以通过工具提前发现。
ts
class Animal {
name: string
constructor(name: string) {
this.name = name
}
speak(): void {
console.log(`${this.name} makes a sound.`)
}
}
const dog = new Animal('Dog')
dog.speak() // OK
dog.bark() // ❌ 报错:Property 'bark' does not exist on type 'Animal'1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 在 JS 中,
dog.bark()会运行时报错,而 TS 在编码阶段就提示错误。
8.2. 类(Class)语法更完善且类型安全
- 虽然 ES6 引入了
class语法,但 JS 的类本质上仍是基于原型的语法糖,缺乏访问控制、类型约束等。 - TS 支持:
- 访问修饰符:
public、private、protected - 构造函数参数属性(自动声明并赋值)
- 抽象类(abstract class)
- 接口实现(implements)
- 访问修饰符:
ts
class BankAccount {
private balance: number = 0 // 外部无法直接访问
constructor(private readonly accountNumber: string) {} // 自动声明 + private
deposit(amount: number): void {
this.balance += amount
}
getBalance(): number {
return this.balance
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- JS 无法阻止外部直接修改
balance,而 TS 通过private保证封装性。
8.3. 接口(Interface)支持契约编程
- TS 的
interface可以定义对象的结构契约,强制类实现特定方法或属性。 - 这是 OOP 中“多态”和“依赖倒置原则”的关键工具。
ts
interface Drawable {
draw(): void
}
class Circle implements Drawable {
draw() {
console.log('Drawing a circle')
}
}
class Square implements Drawable {
draw() {
console.log('Drawing a square')
}
}
function render(shape: Drawable) {
shape.draw() // 多态调用
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- JS 没有接口机制,只能靠文档或运行时检查,容易出错。
8.4. 更好的工具支持(IDE 智能提示、重构等)
- 因为 TS 有类型信息,IDE(如 VS Code)的 TS 语言服务能提供:
- 自动补全
- 重命名重构(安全地重命名类/方法/属性)
- 查找所有实现(Go to Implementations)
- 快速查看类结构
- …… 等诸多功能
- 这些对大型 OOP 项目至关重要。
8.5. 泛型(Generics)支持复用与类型安全
- TS 支持泛型类和泛型方法,可以在保持类型安全的同时实现代码复用。
- 这在集合类(如
List<T>、Map<K, V>)或工厂模式中非常有用。
ts
class Repository<T> {
private items: T[] = []
add(item: T): void {
this.items.push(item)
}
findById(id: string): T | undefined {
return this.items.find(/* ... */)
}
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
8.6. 编译时检查减少运行时错误
- OOP 项目通常结构复杂、类之间依赖多。
- TS 的类型检查能大幅减少因类型不匹配、方法缺失等导致的运行时错误。